﻿// Type: RoMBotDll.Database.ObjectsTable
// Assembly: RoMBotDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Assembly location: D:\Proyectos\TFS\Tests\RoMBotDll\bin\Debug\RoMBotDll.dll

using System;
using System.Collections;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using RoMBot.Classes;
using RoMBot.MemoryLib;

namespace RoMBot.Database
{
    public class ObjectsTable : ThreadedBindingList<GameObject>
    {
        private static ObjectsTable _instancia;

        public static ObjectsTable Instancia
        {
            get { return _instancia ?? ( _instancia = new ObjectsTable() ); }
        }

        public void Update( bool includeUnknow = true, Waypoints.Waypoint distanceIsToWaypoint = null, Func<GameObject, bool> filterFn = null, bool nonParallel = false )
        {
            this.ClearItems();
            var tableSize = Memory.ReadInt( Addresses.staticTableSize );
            var tableAddres = Memory.ReadInt( Addresses.staticTablePtr );
            if ( null == filterFn )
            {
                filterFn = g => true;
            }
            if ( tableSize == 0 || tableAddres == 0 )
            {
                return;
            }
            var arr = Memory.ReadObjectArray<int>( tableAddres, tableSize );
            if ( arr == null )
            {
                return;
            }
            if ( true )
            {
                for ( var index = 0; index < tableSize; index++ )
                {
                    var address = arr[ index ]; //Memory.ReadInt( num2 + index * 4 );
                    if ( address != 0 && address != Bot.Player.Address /*&& Memory.ReadInt( address + Addresses.pawnId_offset ) != 0 */)
                    {
                        var gameObject = new GameObject( address );
                        if ( gameObject.Id == 0 )
                        {
                            continue;
                        }
                        if ( !string.IsNullOrWhiteSpace( gameObject.Name ) && ( includeUnknow || gameObject.Name != GameObject.UnknowName ) )
                        {
                            gameObject.Distance = distanceIsToWaypoint == null ? gameObject.DistanceTo( Bot.Player ) : gameObject.DistanceToWaypoint( distanceIsToWaypoint );// ( float ) Math.Round( Helpers.Distance( gameObject.X, gameObject.Z, Bot.Player.X, Bot.Player.Z ) );
                            if ( filterFn( gameObject ) )
                            {
                                this.Add( gameObject );
                            }
                        }
                    }
                    Thread.Yield();
                }
            }
            else
            {
                Parallel.For( 0, arr.Length, i =>
                {
                    try
                    {
                        var address = ( int ) arr[ i ]; // Memory.ReadInt( num2 + index * 4 );
                        if ( address != 0 && address != Bot.Player.Address && Memory.ReadInt( address + Addresses.pawnId_offset ) != 0 )
                        {
                            var gameObject = new GameObject( address );
                            if ( !string.IsNullOrWhiteSpace( gameObject.Name ) && ( includeUnknow || gameObject.Name != GameObject.UnknowName ) && filterFn( gameObject ) )
                            {
                                gameObject.Distance = distanceIsToWaypoint == null ? gameObject.DistanceTo( Bot.Player ) : gameObject.DistanceToWaypoint( distanceIsToWaypoint ); // ( float ) Math.Round( Helpers.Distance( gameObject.X, gameObject.Z, Bot.Player.X, Bot.Player.Z ) );
                                this.Add( gameObject );
                            }
                        }
                        Thread.Yield();
                    }
                    catch ( Exception e )
                    {
                        Bot.Debug( "Error on objectstable: " + e.Message );
                    }
                } );
            }
        }
    }

    public class TableAddressesArray
    {
    }
}